package com.ybzl.system.mdc;

import org.slf4j.MDC;

import javax.servlet.*;
import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;

/**
 * https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#boot-features-embedded-container
 */
public class MdcFilter implements Filter {

    private static final String CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    private static final Integer CHARS_LEN = 8;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 1、请求入站
        MDC.put("bid", randomString() + "@0");
        // 2、执行过滤器连，以及Servlet
        filterChain.doFilter(servletRequest, servletResponse);
        // 3、执行出站
        MDC.remove("bid");
    }

    /***
     *  生成随机字符串
     * @return
     */
    private static String randomString() {
        final StringBuilder sb = new StringBuilder(CHARS_LEN);
        int baseLength = CHARS.length();
        while (sb.length() < CHARS_LEN) {
            //此处用ThreadLocalRandom 不用Random的感兴趣的同学可以看看这俩的区别
            //主要区别在于多线程高并发环境下 ThreadLocalRandom比Random生成随机数的速度快
            int number = ThreadLocalRandom.current().nextInt(baseLength);
            sb.append(CHARS.charAt(number));
        }
        return sb.toString();
    }
}
